//
//  stat-functions.c
//  PyroTools
//
//  Created by Timothée Poisot on 12/07/11.
//  Copyright 2011 Université Montpellier 2. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>

#include "stat-functions.h"


// Sum of type int
int iSum (int* n, int size)
{
    double isum = 0;
    for(int i = 0;i<size;++i)
    {
        isum = isum + n[i];
    }
    return isum;
}

// Sum of type double
int dSum (double* n, int size)
{
    double isum = 0;
    for(int i = 0;i<size;++i)
    {
        isum = isum + n[i];
    }
    return isum;
}

// Mean of type double
double dMean (double *n, int size)
{
    double dmean = 0;
    for(int i=0;i<size;++i)
    {
        dmean = dmean + n[i];
    }
    dmean = dmean / (double) size;
    return dmean;
}

// Variance of type double
double dVar (double *n, int size)
{
    double dmean = dMean(n,size);
    double sqm = dmean * dmean;
    double* nn = (double*)malloc(size * sizeof(double*));
    for(int i=0;i<size;++i)
    {
        nn[i] = n[i] * n[i];  
    }
    double dmeansq = dMean(nn,size);
    free(nn);
    double dvar = dmeansq - sqm;
    return dvar;
}

// Coefficient of variation of type double
double dCoeffVar (double *n, int size)
{
    double mean = dMean(n,size);
    double stdev =sqrt(dVar(n,size));
    double coeffvar = stdev / mean;
    return coeffvar;
}

// Weighted mean of type double
double dWMean (double *n, double *w, int size)
{
    double tWX = 0;
    double WX = 0;
    double tW = 0;
    for(int i=0;i<size;++i)
    {
        WX = w[i]*n[i];
        tW = tW + w[i];
        tWX = tWX + WX;
    }
    double dwmean = tWX/tW;
    return dwmean;
}

// Weighted SEM of type double
double dWSd (double *n, double *w, int size)
{
    // WVa <- sum(W*(D-WMe)^2)/sum(W)
    // WMe = weighted mean
    double wme = dWMean(n,w,size);
    double sw = dSum(w,size);
    double tpsum = 0;
    for(int i=0;i<size;++i)
    {
        double temp = n[i] - wme;
        temp = temp * temp;
        temp = temp * w[i];
        tpsum = tpsum + temp;
    }
    double dwsd = tpsum/sw;
    return dwsd;
}

// Weighted CV of type double
double dWCV (double *n, double *w, int size)
{
    double wva = sqrt(dWSd(n,w,size));
    double wme = dWMean(n,w,size);
    double dwcv = wva / wme;
    return dwcv;
}